package za.org.jcicada.genss;

import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * URN class for system names. Ensures that only valid names of the form
 * system/type[.instance] can be created and are immutable.
 * 
 * @author rcrida
 * 
 */
public class SystemURN implements Serializable {

    /** Default serial version ID */
    private static final long serialVersionUID = 1L;

    /** Identifying system URNs */
    public static final String URN_SYSTEM = "system";
    
    public static final String NODE_MARKER = "NodeProxy.";
    
    public static final String DATA_STORE_MARKER = "DataStore.";
    
    public static final String PHYSICAL_MARKER = "Physical";
    
    /** The system name part of the URN */
    private final String systemName;

    /** The actual URN is stored in a URI */
    private final URI systemURI;

    /**
     * Constructor given system name
     * 
     * @param systemName in the form type[.instance]
     * @throws URISyntaxException
     */
    public SystemURN(String systemName) throws URISyntaxException {
        String start = URN_SYSTEM + "/";
        if (systemName.startsWith(start)) {
            systemName = systemName.substring(start.length());
        }
        if (systemName.replaceAll("[^.]", "").length() > 1) {
            throw new URISyntaxException(systemName, "More than one period <.> Must be type[.instance]");
        }
        if (systemName.contains("/")) {
            throw new URISyntaxException(systemName, "May not contain /");
        }
        this.systemName = systemName;
        systemURI = new URI(String.format("%s/%s", URN_SYSTEM, systemName));
    }

    /**
     * Constructor given type and instance strings
     * 
     * @param type the system type name
     * @param instance the system instance name
     * @throws URISyntaxException
     */
    public SystemURN(String type, String instance) throws URISyntaxException {
        this(String.format("%s.%s", type, instance));
    }

    public String getSystemName() {
        return systemName;
    }
    
    public String getType() {
    	return systemName.split("\\.")[0];
    }
    
    public boolean isNodeProxy() {
    	return getSystemName().contains(NODE_MARKER);
    }
    
    public boolean isDataStore() {
    	return getSystemName().contains(DATA_STORE_MARKER);
    }
    
    public static SystemURN getPhysicalSystemURN() throws URISyntaxException {
    	return new SystemURN(PHYSICAL_MARKER);
    }

    @Override
    public String toString() {
        return systemURI.toString();
    }

    @Override
    public boolean equals(Object aOther) {
        if (this == aOther)
            return true;
        if (!(aOther instanceof SystemURN))
            return false;
        SystemURN other = (SystemURN) aOther;
        return systemURI.equals(other.systemURI);
    }

    @Override
    public int hashCode() {
        return systemURI.hashCode();
    }
}
